/**
 * 处理图像数据的公共函数
 * @param {ImageData} image_data - 要处理的图像数据对象
 * @param {function(Array, number): void} callback - 处理每个像素的回调函数，接收数据数组和当前像素索引
 * @returns {ImageData} 处理后的图像数据对象
 */
const process_image_data = (image_data, callback) => {
  let data = image_data.data;
  // 循环每次加4表示一个一个像素的处理
  for (let i = 0; i < data.length; i += 4) {
    callback(data, i);
  }
  return image_data;
};

/**
 * 将图像转换为负片效果
 * @param {ImageData} image_data - 要处理的图像数据对象
 * @returns {Object} 包含处理后的图像数据和获取 base64 图像方法的对象
 */
const negative = (image_data) => {
  let data = process_image_data(image_data, (data, i) => {
    data[i + 0] = 255 - data[i + 0]; // 处理红色通道
    data[i + 1] = 255 - data[i + 1]; // 处理绿色通道
    data[i + 2] = 255 - data[i + 2]; // 处理蓝色通道
  });
  return {
    image_data: data,
    get_dase64_image: () => get_dase64_image(data),
  };
};

/**
 * 将图像转换为灰度图
 * @param {ImageData} image_data - 要处理的图像数据对象
 * @param {Array<number>} average_list - 可选的权重数组，长度为3，分别对应红、绿、蓝通道权重
 * @returns {Object} 包含处理后的图像数据和获取 base64 图像方法的对象
 */
const grayscale = (image_data, average_list = []) => {
  let r_average, g_average, b_average;
  if (average_list.length !== 0) {
    r_average = average_list[0];
    g_average = average_list[1];
    b_average = average_list[2];
  }
  let data = process_image_data(image_data, (data, i) => {
    let average;
    if (average_list.length === 0) {
      average = (data[i + 0] + data[i + 1] + data[i + 2]) / 3; // 等权重求平均值
    } else {
      average = data[i + 0] * r_average + data[i + 1] * g_average + data[i + 2] * b_average; // 按权重计算平均值
    }
    data[i + 0] = average; // 设置红色通道
    data[i + 1] = average; // 设置绿色通道
    data[i + 2] = average; // 设置蓝色通道
  });
  return {
    image_data: data,
    get_dase64_image: () => get_dase64_image(data),
  };
};

/**
 * 为图像添加复古效果
 * @param {ImageData} image_data - 要处理的图像数据对象
 * @returns {Object} 包含处理后的图像数据和获取 base64 图像方法的对象
 */
const retro = (image_data) => {
  let data = process_image_data(image_data, (data, i) => {
    data[i + 0] = 0.39 * data[i + 0] + 0.76 * data[i + 1] + 0.18 * data[i + 2]; // 处理红色通道
    data[i + 1] = 0.35 * data[i + 0] + 0.68 * data[i + 1] + 0.16 * data[i + 2]; // 处理绿色通道
    data[i + 2] = 0.27 * data[i + 0] + 0.53 * data[i + 1] + 0.13 * data[i + 2]; // 处理蓝色通道
  });
  return {
    image_data: data,
    get_dase64_image: () => get_dase64_image(data),
  };
};

/**
 * 为图像添加单色掩码效果
 * @param {ImageData} image_data - 要处理的图像数据对象
 * @param {string} type - 掩码类型，可选值为 'r'（红色）、'g'（绿色）、'b'（蓝色）
 * @returns {Object} 包含处理后的图像数据和获取 base64 图像方法的对象
 */
const mask = (image_data, type) => {
  let data = process_image_data(image_data, (data, i) => {
    const average = (data[i + 0] + data[i + 1] + data[i + 2]) / 3; // 计算像素平均值
    data[i + 0] = 0; // 清空红色通道
    data[i + 1] = 0; // 清空绿色通道
    data[i + 2] = 0; // 清空蓝色通道
    if (type === 'r') {
      data[i + 0] = average; // 设置红色通道
    } else if (type === 'g') {
      data[i + 1] = average; // 设置绿色通道
    } else if (type === 'b') {
      data[i + 2] = average; // 设置蓝色通道
    }
  });
  return {
    image_data: data,
    get_dase64_image: () => get_dase64_image(data),
  };
};

/**
 * 调整图像透明度
 * @param {ImageData} image_data - 要处理的图像数据对象
 * @param {number} alpha - 透明度系数，范围在 0 到 1 之间
 * @returns {Object} 包含处理后的图像数据和获取 base64 图像方法的对象
 */
const transparent = (image_data, alpha) => {
  let data = process_image_data(image_data, (data, i) => {
    data[i + 3] = alpha * data[i + 3]; // 调整透明度通道
  });
  return {
    image_data: data,
    get_dase64_image: () => get_dase64_image(data),
  };
};

/**
 * 调整图像亮度
 * @param {ImageData} image_data - 要处理的图像数据对象
 * @param {number} brightness - 亮度调整值，范围在 -255 到 255 之间
 * @returns {Object} 包含处理后的图像数据和获取 base64 图像方法的对象
 */
const shading = (image_data, brightness) => {
  // 限制亮度值在 -255 到 255 之间
  brightness = Math.max(-255, Math.min(255, brightness));
  let data = process_image_data(image_data, (data, i) => {
    if (brightness < 0) {
      data[i + 0] = Math.max(0, data[i + 0] + brightness); // 降低红色通道亮度
      data[i + 1] = Math.max(0, data[i + 1] + brightness); // 降低绿色通道亮度
      data[i + 2] = Math.max(0, data[i + 2] + brightness); // 降低蓝色通道亮度
    } else {
      data[i + 0] = Math.min(255, data[i + 0] + brightness); // 提高红色通道亮度
      data[i + 1] = Math.min(255, data[i + 1] + brightness); // 提高绿色通道亮度
      data[i + 2] = Math.min(255, data[i + 2] + brightness); // 提高蓝色通道亮度
    }
  });
  return {
    image_data: data,
    get_dase64_image: () => get_dase64_image(data),
  };
};

const get_dase64_image = (data) => {
  var canvas = document.createElement('canvas');
  canvas.width = data.width;
  canvas.height = data.height;
  var ctx = canvas.getContext('2d');
  ctx.putImageData(data, 0, 0);
  var dataURL = canvas.toDataURL();
  canvas = null;
  ctx = null;
  return dataURL;
};

// 导出一个对象
const imageUtils = {
  negative,
  grayscale,
  retro,
  mask,
  transparent,
  shading,
  get_dase64_image,
};

export default imageUtils;
